package com.fire.control.system.module.user.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.fire.control.system.config.redis.RedisService;
import com.fire.control.system.dto.UserDTO;
import com.fire.control.system.dto.app.AppFileVo;
import com.fire.control.system.dto.app.AppHandleVo;
import com.fire.control.system.entity.Duty;
import com.fire.control.system.entity.Role;
import com.fire.control.system.entity.User;
import com.fire.control.system.entity.UserGetuiInfo;
import com.fire.control.system.module.duty.service.IDutyService;
import com.fire.control.system.module.file.controller.app.AppFileController;
import com.fire.control.system.module.file.service.AppFileService;
import com.fire.control.system.module.role.dao.RoleMapper;
import com.fire.control.system.module.user.dao.UserMapper;
import com.fire.control.system.module.user.dao.UserRepository;
import com.fire.control.system.module.user.service.IUserService;
import com.fire.control.system.module.warning.service.AppWarningService;
import com.fire.control.system.statics.Key;
import com.fire.control.system.statics.ResponseMessage;
import com.fire.control.system.support.protocol.comman.ProtocolSelector;
import com.fire.control.system.support.protocol.comman.ResponseJsonProtocol;
import com.fire.control.system.support.protocol.comman.ResponseProtocol;
import com.fire.control.system.support.protocol.duty.DutyRequestProtocol;
import com.fire.control.system.support.protocol.sys.SystemRequestProtol;
import com.fire.control.system.support.protocol.user.UserRequestProtocol;
import com.fire.control.system.support.util.SmsUtil;
import com.fire.control.system.support.util.StaticValue;
import com.fire.control.system.support.util.XdaoDate;
import com.fire.control.system.support.util.XdaoPassword;
import com.github.pagehelper.StringUtil;

@Service("userService")
public class UserServiceImpl implements IUserService {

	@Autowired
	private UserRepository userRepository;
	@Autowired
	private ProtocolSelector protocolSelector;
	@Autowired
	private AppFileService appFileService;
	@Autowired
	private IDutyService dutyService;
	@Autowired
	private AppWarningService appWarningService;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private RedisService redisService;
	@Autowired
	private RoleMapper roleMapper;
	@Autowired
	private SmsUtil smsUtil;
	@Autowired
	private AppFileController appFileController;
	
	private String idenCode;

	/**
	 * <p>
	 * Title: getUserDetail
	 * </p>
	 * <p>
	 * Description: 获取用户详细资料
	 * </p>
	 * 
	 * @param requestProtocol
	 * @return
	 * @see com.fire.control.system.module.user.service.IUserService#getUserDetail(com.fire.control.system.support.protocol.user.UserRequestProtocol)
	 */
	@Override
	public ResponseProtocol getUserDetail(UserRequestProtocol requestProtocol, UserDTO user) {
		// TODO Auto-generated method stub
		ResponseProtocol response = protocolSelector.choose(requestProtocol);

		User userDetail = userMapper.getById(user.getUserId());
		if (!userDetail.equals(null)) {
			userDetail.setUserIcon(StaticValue.file_server_domain+userDetail.getUserIcon());
			ResponseMessage.CODE_200.messageToProtocol(response).setMessage("用户资料获取成功!");;
			response.setDate(new XdaoDate());
			response.setData(userDetail);
		} else {
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户资料获取失败!");;
			response.setDate(new XdaoDate());
		}
		return response;
	}

	/**
	 * <p>
	 * Title: updateUserInfo
	 * </p>
	 * <p>
	 * Description: 修改个人资料
	 * </p>
	 * 
	 * @param requestProtocol
	 * @return
	 * @see com.fire.control.system.module.user.service.IUserService#updateUserInfo(com.fire.control.system.support.protocol.user.UserRequestProtocol)
	 */
	@Override
	public ResponseProtocol updateUserInfo(UserRequestProtocol requestProtocol, UserDTO user) {
		// TODO Auto-generated method stub
		ResponseProtocol response = protocolSelector.choose(requestProtocol);
		String type = requestProtocol.getType();

		String value = requestProtocol.getValue();

		User u = userRepository.findOne(user.getUserId());

		// 将值赋给该用户
		switch (type) {
		case "name":
			u.setName(value);
			break;
		case "sex":
			u.setSex(value);
			break;
		case "telphoneNumber":
			this.validateUserInfo(requestProtocol, response);
			return response;
		case "address":
			u.setAddress(value);
			break;
		case "userIcon":
			u.setUserIcon(value);
			break;
		default:
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户信息修改失败!");
			return response;
		}

		User returnUser = userRepository.saveAndFlush(u);

		if (returnUser != null) {
			ResponseMessage.CODE_200.messageToProtocol(response).setMessage("用户信息修改成功!");
		} else {
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户信息修改失败!");
		}
		return response;
	}

	/**
	 * @author liuxincheng
	 * @Title: validateUserInfo
	 * @Description: TODO(校验用户信息)
	 * @param @param
	 *            requestProtocol
	 * @param @return
	 *            设定文件
	 * @return ResponseProtocol 返回类型
	 * @throws null
	 */
	public ResponseProtocol validateUserInfo(UserRequestProtocol requestProtocol, ResponseProtocol response) {
		String telphoneNumber = requestProtocol.getValue();
		String passWord = requestProtocol.getPassWord();

		User u = userMapper.getUserByCondition(telphoneNumber, passWord);

		if (u != null) {
			ResponseMessage.CODE_200.messageToProtocol(response).setMessage("用户信息校验成功!");
		} else {
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户信息校验失败!");
		}
		return response;
	}

	/**
	 * @author liuxincheng
	 * @Title: sendSms
	 * @Description: TODO(发送验证码)
	 * @param @param
	 *            requestProtocol
	 * @param @return
	 *            设定文件
	 * @return ResponseProtocol 返回类型
	 * @throws null
	 */
	@Override
	public ResponseProtocol sendSms(UserRequestProtocol requestProtocol) {
		boolean flag = false;
		ResponseProtocol response = protocolSelector.choose(requestProtocol);
		String telNumber = requestProtocol.getTelphoneNumber();
		idenCode = XdaoPassword.getRandomCode();
		flag = smsUtil.sendSmsCode(telNumber, idenCode);

		if (flag) {
			response.setData(idenCode);
			response.setDate(new XdaoDate());
			redisService.set(Key.idenCode + telNumber, idenCode, Key.idenCode.getExpire());
			redisService.set(Key.redis_key_lora_phoneNumber + telNumber, telNumber,
					Key.redis_key_lora_phoneNumber.getExpire());
			ResponseMessage.CODE_200.messageToProtocol(response).setMessage("验证码发送成功!");
		} else {
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("验证码发送失败!");
			response.setDate(new XdaoDate());
		}
		return response;
	}

	/**
	 * @author liuxincheng @Title: changeTelphoneNumber @Description:
	 *         TODO(校验并添加电话号码) @param @param requestProtocol @param @param
	 *         response @param @return 设定文件 @return ResponseProtocol
	 *         返回类型 @throws
	 */
	@Override
	public ResponseProtocol validateTelphoneNumber(UserRequestProtocol requestProtocol, UserDTO user) {
		ResponseProtocol response = protocolSelector.choose(requestProtocol);
		String inputCode = requestProtocol.getIdenCode();
		String phoneNumber = requestProtocol.getTelphoneNumber();
		String idencode = redisService.get(Key.idenCode + phoneNumber);
		String telPhone = redisService.get(Key.redis_key_lora_phoneNumber + phoneNumber);

		if (phoneNumber != null && phoneNumber.equals(telPhone)) {
			if (inputCode != null && inputCode.equals(idencode)) {
				User u = userRepository.findOne(user.getUserId());
				u.setTelNumber(phoneNumber);
				User returnUser = userRepository.saveAndFlush(u);
				if (returnUser != null) {
					ResponseMessage.CODE_200.messageToProtocol(response).setMessage("电话号码修改成功!");
				} else {
					ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户信息修改失败!");
				}
			} else {
				ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户信息修改失败!");
			}
		} else {
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户信息修改失败!");
		}
		return response;
	}

	/**
	 * <p>
	 * Title: uploadUserIcon
	 * </p>
	 * <p>
	 * Description: 上传用户头像
	 * </p>
	 * 
	 * @param requestProtocol
	 * @param request
	 * @param user
	 * @return
	 * @see com.fire.control.system.module.user.service.IUserService#uploadUserIcon(com.fire.control.system.support.protocol.user.UserRequestProtocol,
	 *      org.springframework.web.multipart.MultipartHttpServletRequest,
	 *      com.fire.control.system.dto.UserDTO)
	 */
	@Override
	public ResponseProtocol uploadUserIcon (MultipartHttpServletRequest request,
			UserDTO user) {
		// TODO Auto-generated method stub
		ResponseProtocol response = new ResponseJsonProtocol();
		
		ResponseProtocol res = appFileController.uploadFile(request);
		User u = userRepository.findOne(user.getUserId());
		
		if(res.getData() instanceof ArrayList<?>){
			List<AppFileVo> appFileVoList = (ArrayList<AppFileVo>)res.getData();
			for(AppFileVo file : appFileVoList){
				u.setUserIcon(file.getUrl());
			}
		}
		
		User returnUser = userRepository.saveAndFlush(u);
		if(returnUser != null){
			response.setData(user.getUserIcon());
			ResponseMessage.CODE_200.messageToProtocol(response).setMessage("用户头像修改成功!");
		}else{
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户头像修改失败!");
		}
		return response;
	}

	/**
	 * <p>
	 * Title: modifyPassword
	 * </p>
	 * <p>
	 * Description: 修改用户密码
	 * </p>
	 * 
	 * @param requestProtocol
	 * @return
	 * @see com.fire.control.system.module.user.service.IUserService#modifyPassword(com.fire.control.system.support.protocol.sys.SystemRequestProtol)
	 */
	@Override
	public ResponseProtocol modifyPassword(SystemRequestProtol requestProtocol, UserDTO user) {
		// TODO Auto-generated method stub
		ResponseProtocol response = protocolSelector.choose(requestProtocol);

		User u = userRepository.findOne(user.getUserId());

		String originalPassword = requestProtocol.getOriginalPassword();

		String newPassword = requestProtocol.getNewPassword();

		String confirmPassword = requestProtocol.getConfirmPassword();

		if (!StringUtil.isEmpty(originalPassword) && originalPassword.equals(XdaoPassword.decrypt(u.getPassword()))) {
			if (!StringUtil.isEmpty(newPassword) && !StringUtil.isEmpty(confirmPassword)
					&& newPassword.equals(confirmPassword)) {
				u.setPassword(XdaoPassword.encrypt(newPassword));
				User returnUser = userRepository.saveAndFlush(u);
				if (returnUser != null) {
					ResponseMessage.CODE_200.messageToProtocol(response).setMessage("密码修改成功!");
					response.setData(returnUser);
				} else {
					ResponseMessage.CODE_400.messageToProtocol(response).setMessage("密码修改失败!");
				}
			} else {
				ResponseMessage.CODE_400.messageToProtocol(response).setMessage("两次密码输入不一致!");
			}
		} else {
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("用户密码输入不匹配!");
		}
		return response;
	}

	/**
	 * <p>
	 * Title: workRecord
	 * </p>
	 * <p>
	 * Description: 工作记录
	 * </p>
	 * 
	 * @param requestProtocol
	 * @return
	 * @see com.fire.control.system.module.user.service.IUserService#workRecord(com.fire.control.system.support.protocol.user.UserRequestProtocol)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public ResponseProtocol workRecord(DutyRequestProtocol requestProtocol, Pageable p, UserDTO user) {
		// TODO Auto-generated method stub
		ResponseProtocol response = protocolSelector.choose(requestProtocol);
		// 签到列表数据获取
		ResponseProtocol signList = dutyService.signInList(requestProtocol, p);
		// 报警列表数据获取
		ResponseProtocol warningList = appWarningService.handleLog(requestProtocol, user);

		Map<String, Object> dataMap = new HashMap<String, Object>();

		if (!signList.getData().equals(null) && !warningList.getData().equals(null)) {
			Page<Duty> dutyPage = (Page<Duty>) signList.getData();
			dataMap.put("dutyPage", dutyPage);

			Map<String, Object> warningMap = (Map<String, Object>) warningList.getData();

			// 误报处理
			Map<String, Object> misinformationMap = (Map<String, Object>) warningMap.get("misinformationList");
			List<AppHandleVo> misinformationList = (List<AppHandleVo>) misinformationMap.get("content");

			// 报警处理
			Map<String, Object> faultMap = (Map<String, Object>) warningMap.get("faultList");
			List<AppHandleVo> faultList = (List<AppHandleVo>) faultMap.get("content");

			dataMap.put("misinformationList", misinformationList);
			dataMap.put("faultList", faultList);

			ResponseMessage.CODE_200.messageToProtocol(response);
			response.setData(dataMap);
		} else {
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("数据返回失败!");
		}
		return response;
	}

	/**
	 * @Title: saveUserGetuiInfo
	 * @Description: TODO(保存用户个推信息)
	 * @author wanbo
	 * @date 2017年7月1日 下午4:43:43
	 * @param cid
	 * @param userId
	 * @return
	 */
	public int saveUserGetuiInfo(String cid, String userId) {
		UserGetuiInfo getuiInfo = userMapper.getUserGetuiInfo(userId);
		if (getuiInfo == null) {
			getuiInfo = new UserGetuiInfo();
			getuiInfo.setUserId(userId);
			getuiInfo.setCid(cid);
			return userMapper.saveUserGetuiInfo(getuiInfo);
		} else {
			return userMapper.updateUserGetuiInfo(cid, userId);
		}

	}

	/**
	 * @Title: createUserToken
	 * @Description: TODO(创建或更新用户token)
	 * @author wanbo
	 * @date 2017年7月1日 下午4:44:11
	 * @param userId
	 */
	public String createUserToken(String userId) {
		String token = userId + "_" + UUID.randomUUID().toString().replace("-", "");
		String dbToken = userMapper.getUserToken(userId);
		if (StringUtils.isNotEmpty(dbToken)) {
			userMapper.updateUserToken(userId, token);
		} else {
			userMapper.insertUserToken(userId, token);
		}
		redisService.set(Key.redis_key_lora_token_user_id_ + userId, token,
				Key.redis_key_lora_token_user_id_.getExpire());
		return token;
	}

	/**
	 * @Title: getUserToken
	 * @Description: TODO(获取用户token)
	 * @author wanbo
	 * @date 2017年7月1日 下午4:57:14
	 * @param userId
	 * @return
	 */
	public String getUserToken(String userId) {
		String token = redisService.get(Key.redis_key_lora_token_user_id_ + userId);
		if (StringUtils.isEmpty(token)) {
			token = userMapper.getUserToken(userId);
			redisService.set(Key.redis_key_lora_token_user_id_ + userId, token,
					Key.redis_key_lora_token_user_id_.getExpire());
		}
		return token;
	}

	//只允许APP端获取用户信息用
	public UserDTO getUserInfo(String userId) {
		UserDTO userDto = redisService.getObject(Key.redis_key_lora_user_id_ + userId, UserDTO.class);
		if (userDto == null) {
			userDto = new UserDTO();
			User user = userRepository.getUserInfo(userId);
			if (user != null) {
				userDto.setUser(user);
				userDto.setCompany(user.getCompany());
				userDto.setRole(roleMapper.getRoleByUserId(user.getId()));
			}
			redisService.setObject(Key.redis_key_lora_user_id_ + userId, userDto,
					Key.redis_key_lora_user_id_.getExpire());
		}
		return userDto;
	}

	/**
	 * <p>Title: getCurrentRoles</p>
	 * <p>Description: 获取当前登陆人员的所属角色</p>
	 * @param requestProtocol
	 * @param user
	 * @return
	 * @see com.fire.control.system.module.user.service.IUserService#getCurrentRoles(com.fire.control.system.support.protocol.sys.SystemRequestProtol, com.fire.control.system.dto.UserDTO)
	 */
	@Override
	public ResponseProtocol getCurrentRoles(SystemRequestProtol requestProtocol, UserDTO user) {
		// TODO Auto-generated method stub
		ResponseProtocol response = protocolSelector.choose(requestProtocol);
		
		User u = userRepository.findOne(user.getUserId());
		
		Collection<Role> roleList = u.getRole();
		
		if(!roleList.isEmpty() && roleList.size()>0){
			response.setData(roleList);
			ResponseMessage.CODE_200.messageToProtocol(response).setMessage("角色获取成功!");
		}else{
			ResponseMessage.CODE_400.messageToProtocol(response).setMessage("角色获取失败!");
		}
		return response;
	}
}
